use clap::{App, Arg};
use sntp::{NtpServer, NtpTimestamp};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

fn main() {
    let matches = App::new("sntpd")
        .version("1.0")
        .author("Varphone Wong <varphone@qq.com>")
        .about("Simple NTP Server")
        .arg(
            Arg::with_name("bind-address")
                .short("b")
                .long("bind-address")
                .takes_value(true)
                .min_values(1)
                .value_name("IP:PORT")
                .help("Sets the bind address(es)"),
        )
        .arg(
            Arg::with_name("verbose")
                .short("v")
                .long("verbose")
                .multiple(true)
                .help("Use verbose output (-vv very verbose)"),
        )
        .get_matches();

    let addrs: Vec<_> = if let Some(iter) = matches.values_of("bind-address") {
        iter.collect()
    } else {
        vec!["127.0.0.1:9123"]
    };

    let level = match matches.occurrences_of("verbose") {
        0 => log::LevelFilter::Warn,
        1 => log::LevelFilter::Info,
        2 => log::LevelFilter::Debug,
        _ => log::LevelFilter::Trace,
    };

    env_logger::builder()
        .filter(None, level)
        .parse_default_env()
        .init();

    let server = Arc::new(NtpServer::new(&addrs).expect("创建 NTP 服务失败"));

    {
        let server = Arc::clone(&server);
        thread::spawn(move || {
            let mut ref_time = chrono::Utc::now().naive_utc();
            loop {
                if let Ok(ts) = NtpTimestamp::try_from(ref_time) {
                    server.update_ref_ts(ts);
                }
                thread::sleep(Duration::from_secs(1));
                ref_time += chrono::Duration::seconds(1);
            }
        });
    }

    server.run();
}
